package prometheus

import (
	"fmt"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"net/http"
)

// https://blog.51cto.com/root/3009719
// https://blog.csdn.net/cristianoxm/article/details/128726963
// https://blog.csdn.net/weixin_44268481/article/details/121302080

type HostMonitor struct {
	cpuDesc     *prometheus.Desc
	memDesc     *prometheus.Desc
	ioDesc      *prometheus.Desc
	labelValues []string
}

func NewHostMonitor() *HostMonitor {
	return &HostMonitor{
		cpuDesc: prometheus.NewDesc(
			"host_cpu",
			"get host cpu",
			// 动态标签 key 列表
			[]string{"instance_id", "instance_name", "ddddeeeee"},
			// 今天标签
			prometheus.Labels{"model11": "cpu"},
		),
		ioDesc: prometheus.NewDesc(
			"host_io",
			"get host io",
			// 动态标签 key 列表
			[]string{"instance_id", "instance_name", "ddddd"},
			// 今天标签
			prometheus.Labels{"model2": "io"},
		),
		memDesc: prometheus.NewDesc(
			"host_mem",
			"dasda",
			[]string{"instance_id1", "instance_name1", "dasdasd"},
			prometheus.Labels{
				"model1": "mem",
			},
		),
		labelValues: []string{"myhost", "你大爷", "ddadad"},
	}
}

/**
# HELP host_cpu get host cpu
# TYPE host_cpu gauge
host_cpu{ddddeeeee="ddadad",instance_id="myhost",instance_name="你大爷",model11="cpu"} 70
# HELP host_io get host io
# TYPE host_io gauge
host_io{ddddd="ddadad",instance_id="myhost",instance_name="你大爷",model2="io"} 70
# HELP host_mem dasda
# TYPE host_mem gauge
host_mem{dasdasd="ddadad",instance_id1="myhost",instance_name1="你大爷",model1="mem"} 70
# HELP promhttp_metric_handler_errors_total Total number of internal errors encountered by the promhttp metric handler.
# TYPE promhttp_metric_handler_errors_total counter
promhttp_metric_handler_errors_total{cause="encoding"} 0
promhttp_metric_handler_errors_total{cause="gathering"} 0

prometheus exporter 的协议是

# HELP host_io get host io
# TYPE host_io gauge
host_io{ddddd="ddadad",instance_id="myhost",instance_name="你大爷",model2="io"} 70

其中
# HELP host_io get host io
# TYPE host_io gauge
是描述信息，
host_io是指标名称， gauge是指标类型，get host io是帮助信息

host_io{ddddd="ddadad",instance_id="myhost",instance_name="你大爷",model2="io"} 70
是指标，metrics
其中，ddddd="ddadad",instance_id="myhost",instance_name="你大爷"是动态标签，可以变化，
model2="io" 是静态标签，不可改变

*/

// Describe 实现 Describe 接口，传递指标到channel
func (h *HostMonitor) Describe(ch chan<- *prometheus.Desc) {
	ch <- h.cpuDesc
	ch <- h.memDesc
	ch <- h.ioDesc
}

// Collect 实现collect 接口，将执行抓取函数并返回数据
func (h *HostMonitor) Collect(ch chan<- prometheus.Metric) {
	ch <- prometheus.MustNewConstMetric(h.cpuDesc, prometheus.GaugeValue, 70, h.labelValues...)
	ch <- prometheus.MustNewConstMetric(h.ioDesc, prometheus.GaugeValue, 70, h.labelValues...)
	ch <- prometheus.MustNewConstMetric(h.memDesc, prometheus.GaugeValue, 70, h.labelValues...)
}

// StartAgent 实现http 访问
func StartAgent() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(fmt.Sprintf("发生了错误。。。 %v", err))
		}
	}()

	// 创建自定义注册表
	registry := prometheus.NewRegistry()

	// 注册自定义采集器
	registry.MustRegister(NewHostMonitor())

	// 暴露 metrics
	http.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{Registry: registry}))
	http.ListenAndServe(":10000", nil)
}
